package mysql

import (
	"CampusCloudAid/models"
	"fmt"
	"time"

	"gorm.io/gorm"

	"go.uber.org/zap"
)

func GetAllTasks() (tasks []*models.Tasks, err error) {
	err = Conn.Table("tasks").Order("publish_time DESC").Find(&tasks).Error
	if err != nil {
		zap.L().Error("GetAllTasks() Select failed", zap.Error(err))
		return nil, err
	}
	return tasks, nil
}

// GetTasksByConditional 模糊查询
func GetTasksByConditional(p *models.ParamTasksByConditional) (tasks *[]models.Tasks, err error) {
	query := Conn.Debug().Table("tasks").
		Select("id,task_name,task_type,publisher_id,receiver_id,publish_time,end_time,task_status")
	if p.TaskName != "" {
		query = query.Where("task_name LIKE ?", "%"+p.TaskName+"%")
	}
	if p.PublisherName != "" {
		query = query.Or("publisher_id IN (SELECT uid FROM users WHERE nickname LIKE ?)", "%"+p.PublisherName+"%")
	}
	if p.TaskType != "" {
		query = query.Or("task_type = ?", p.TaskType)
	}
	if p.PublishTime != "" {
		query = query.Or("publish_time >= ?", p.PublishTime)
	}
	if p.EndTime != "" {
		query = query.Or("end_time <= ?", p.EndTime)
	}
	if p.TaskStatus != "" {
		query = query.Or("task_status = ?", p.TaskStatus)
	}
	res := query.Find(&tasks)
	if res.Error != nil {
		zap.L().Error("GetTasksByConditional(p *models.ParamTasksByConditional) Select failed", zap.Error(err))
		return nil, res.Error
	}
	return tasks, nil
}

// 获取任务详情
func GetTask(id int64) (task *models.Tasks, err error) {
	err = Conn.Debug().Where("id=?", id).First(&task).Error
	if err != nil {
		zap.L().Error("GetTask(id int) First failed", zap.Error(err))
		//任务不存在
		return nil, ErrInvalidId
	}
	return task, nil
}

// 接收任务
func UpdateReceiveInfo(id int, uid int64) (err error) {
	// 构建更新的数据
	data := map[string]interface{}{
		"task_status":   "已接收", //任务状态，钱在任务中，目前不进行改变；
		"receiver_id":   uid,
		"receiver_time": time.Now(), // 假设使用当前时间
	}
	// 执行更新操作
	if err := Conn.Debug().Model(&models.Tasks{}).Where("id = ?", id).Updates(data).Error; err != nil {
		zap.L().Error("UpdateReceiveInfo(id int, uid int64) Updates failed", zap.Error(err))
		return err
	}
	return
}

// SubmitVoucherTask 已提交，待确认（荒废）
func SubmitVoucherTask(id int, completionImage string) (err error) {
	// 构建更新的数据
	data := map[string]interface{}{
		"task_status":      "已提交，待确认", //任务等待对方确认
		"completion_image": completionImage,
		//"end_time":         time.Now(),
	}
	// 执行更新操作
	if err := Conn.Debug().Model(&models.Tasks{}).Where("id = ?", id).Updates(data).Error; err != nil {
		zap.L().Error("UpdateReceiveInfo(id int, uid int64) Updates failed", zap.Error(err))
		return err
	}
	return
}

// InputTask 修改状态；
func InputTask(id int64) (err error) {
	//先查询任务的状态是否是已提交，待确认（任务凭证不是必须的？。。。）
	//查询任务发起人id和token中id是否为同一人

	// 构建更新的数据
	data := map[string]interface{}{
		"task_status": "已提交，待确认",  //任务等待对方确认
		"end_time":    time.Now(), // 任务结束时间，
	}
	// 执行更新操作
	if err := Conn.Debug().Model(&models.Tasks{}).Where("id = ?", id).Updates(data).Error; err != nil {
		zap.L().Error("UpdateReceiveInfo(id int, uid int64) Updates failed", zap.Error(err))
		return err
	}
	// 调用修改钱包表的方法
	task, _ := GetTask(id) // 根据任务ID获取任务信息
	err = ChangeTaskStatusToPendingConfirmation(task.Id, task.ReceiverId, task.PaymentFee)

	return
}

// QueryPendingTaskIDs 查询数据库中所有状态为已提交待确认的任务
func QueryPendingTaskIDs(Conn *gorm.DB) ([]int64, error) {
	var taskIDs []int64

	// 执行查询操作
	result := Conn.Table("tasks").
		Where("end_time BETWEEN ? AND ? AND task_status = ?", time.Now(), time.Now().Add(-48*time.Hour), "已提交，待确认").
		Pluck("id", &taskIDs)
	if result.Error != nil {
		zap.L().Error("从token查询用户失败：", zap.Error(result.Error))
		return nil, result.Error
	}

	fmt.Println(taskIDs)
	return taskIDs, nil
}

//func QueryPendingTaskIDs() ([]int64, error) {
//	var taskIDs []int64
//	err := Conn.Model(&models.Tasks{}).
//		Select("id").
//		Where("end_time BETWEEN ? AND ? AND task_status = ?", time.Now().Add(-48*time.Hour), time.Now(), "已提交，待确认").
//		Pluck("id", &taskIDs).Error
//	if err != nil {
//		// 处理查询错误
//		return nil, err
//	}
//	fmt.Println(taskIDs)
//	return taskIDs, nil
//}

// FindPendingTasks 查询48小时内状态为"已提交，待确认"的任务ID
//func FindPendingTasks() (taskIDs []int64, err error) {
//	var tasks []*models.Tasks
//	// 构建查询条件
//	query := Conn.Table("tasks").
//		Where("task_status = ? AND end_time BETWEEN ? AND ?", "已提交，待确认", time.Now().Add(-48*time.Hour), time.Now()).
//		Select("id")
//
//	// 执行查询操作
//	err = query.Find(&tasks).Error
//	if err != nil {
//		zap.L().Error("FindPendingTasksIDs() Select failed", zap.Error(err))
//		return nil, err
//	}
//
//	// 提取任务ID
//	for _, task := range tasks {
//		taskIDs = append(taskIDs, task.Id)
//	}
//
//	return taskIDs, nil
//}

func FindPendingTaskIDs() (taskIDs []int64, err error) {
	// 执行查询操作
	result := Conn.Table("tasks").
		Where("task_status = ? AND end_time BETWEEN ? AND ?", "已提交，待确认", time.Now().Add(-48*time.Hour), time.Now()).
		Pluck("id", &taskIDs)
	if result.Error != nil {
		zap.L().Error("FindPendingTaskIDs() Select failed", zap.Error(result.Error))
		return nil, result.Error
	}

	return taskIDs, nil
}

// checkAndUpdateTasks 查询并更新任务状态
func checkAndUpdateTasks() {
	zap.L().Error("进入函数：")
	// 查询数据库中所有状态为已提交待确认的任务
	pendingConfirmationTaskIDs, err := FindPendingTaskIDs()

	zap.L().Error("输入所有id")
	if err != nil {
		zap.L().Error("Error querying pending tasks:", zap.Error(err))

		return
	}

	// 遍历每个任务 ID，根据条件执行相应的操作
	for _, taskID := range pendingConfirmationTaskIDs {
		//// 根据任务 ID 获取完整的任务对象
		////task, err := GetTaskByID(tasks.Id)
		////fmt.Println(tasks)
		////if err != nil {
		////	fmt.Println("Error getting task by ID:", err)
		////	continue
		////}
		//
		//err = ChangeTaskStatusToCompleted(task.Id, task.ReceiverId, task.PaymentFee)
		//if err != nil {
		//	fmt.Println("Error updating task status:", err)
		//}
		err := FinishTask(taskID)
		if err != nil {
			fmt.Println("Error finishing task:", err)
		}
	}
}

// QueryPendingTaskIDs 查询数据库中所有状态为已提交待确认的任务
//func QueryPendingTaskIDs(Conn *gorm.DB) ([]int64, error) {
//	var taskIDs []int64
//
//	// 执行查询操作
//	result := Conn.Table("tasks").
//		Where("end_time BETWEEN ? AND ? AND task_status = ?", time.Now(), time.Now().Add(-48*time.Hour), "已提交，待确认").
//		Pluck("id", &taskIDs)
//	if result.Error != nil {
//		zap.L().Error("从token查询用户失败：", zap.Error(result.Error))
//		return nil, result.Error
//	}
//
//	fmt.Println(taskIDs)
//	return taskIDs, nil
//}

// FinishTask 确认完成任务
func FinishTask(id int64) (err error) {
	//先查询任务的状态是否是已提交，待确认（任务凭证不是必须的？。。。）
	//查询任务发起人id和token中id是否为同一人

	// 构建更新的数据
	data := map[string]interface{}{
		"task_status": "已完成", //任务等待对方确认

		"system_confirm_time": time.Now(), //任务确认时间
	}
	// 执行更新操作
	if err := Conn.Debug().Model(&models.Tasks{}).Where("id = ?", id).Updates(data).Error; err != nil {
		zap.L().Error("UpdateReceiveInfo(id int, uid int64) Updates failed", zap.Error(err))
		return err
	}
	// 调用修改钱包表的方法，更新钱包信息
	task, _ := GetTask(id) // 根据任务ID获取任务信息
	err = ChangeTaskStatusToCompleted(task.Id, task.ReceiverId, task.PaymentFee)
	//  保存流水记录到数据库
	//moneyFlow := models.MoneyFlow{
	//	FromUserID:  task.PublisherId, // 任务发起人id
	//	ToUserID:    task.ReceiverId,  // 任务接收者id
	//	Amount:      task.PaymentFee,  // 任务金额
	//	ArrivalTime: time.Now(),       // 当前时间
	//	Status:      "任务转账",           // 充值状态
	//	TaskID:      task.Id,          // 任务的ID
	//}
	//err = CreateFlow(moneyFlow)
	//if err != nil {
	//	return err
	//}
	return nil
}

// DownTask 下架任务
func DownTask(id int64) (err error) {
	// 构建更新的数据
	data := map[string]interface{}{
		"task_status": "已下架", //任务自动下架或者发起人取消

		"end_time": time.Now(),
	}
	// 执行更新操作
	if err := Conn.Debug().Model(&models.Tasks{}).Where("id = ?", id).Updates(data).Error; err != nil {
		zap.L().Error("UpdateReceiveInfo(id int, uid int64) Updates failed", zap.Error(err))
		return err
	}
	task, _ := GetTask(id) // 根据任务ID获取任务信息
	err = TaskUnpublishMoney(task.PublisherId, task.ReceiverId, task.PaymentFee)
	return
}

// GetTaskPublisherID 工具类方法 判断任务id对应的用户id是什么；//根据任务id获取任务发起人id，用以比较是否为一人
func GetTaskPublisherID(taskID int) (int64, error) {
	var publisherID int64
	if err := Conn.Model(&models.Tasks{}).Where("id = ?", taskID).Pluck("publisher_id", &publisherID).Error; err != nil {
		return 0, err
	}
	return publisherID, nil
}

// GetTaskStatus 工具类方法 判断任务id对应的任务状态是什么；
func GetTaskStatus(taskID int) (string, error) {
	var taskStatus string
	if err := Conn.Model(&models.Tasks{}).Where("id = ?", taskID).Pluck("task_status", &taskStatus).Error; err != nil {
		return "error", err
	}
	return taskStatus, nil
}

//---------------------------------------------------------

// GetTask 根据任务id获取任务
//func GetTask(id int) (task *models.Tasks, err error) {
//	res := Conn.Debug().Find(&task, id).Error
//	if res != nil {
//		zap.L().Error("Conn.Find(&task, id).Error", zap.Error(err))
//		return
//	}
//	return task, nil
//}

// CreateTask 创建任务方法
func CreateTask(p *models.CreateTask) (err error) {

	res := Conn.Debug().Create(&p).Error
	if res != nil {

		zap.L().Error("任务创建失败", zap.Error(err))
		fmt.Println("-------", zap.Error(err))
		return
	}
	return
}

// ReceiveTasks 更新任务数据
func ReceiveTasks(id int, task *models.Tasks) (err error) {
	res := Conn.Debug().Where("id=?", id).Updates(&task).Error
	if res != nil {
		zap.L().Error("Conn.Updates(&task).Error", zap.Error(err))
		fmt.Println("-------", zap.Error(err))
		return
	}
	return
}

// GetReceivePhone 获取任务中接收人的手机号
func GetReceivePhone(id int) (phone string, err error) {
	var task *models.Tasks
	err = Conn.Debug().Where("id=?", id).First(&task).Error
	if err != nil {
		zap.L().Error("GetTask(id int) First(&task) failed", zap.Error(err))
		//任务不存在
		return "", ErrInvalidId
	}
	var user *models.Users
	err = Conn.Debug().Where("uid=?", task.ReceiverId).First(&user).Error
	if err != nil {
		zap.L().Error("GetTask(id int) First(&user) failed", zap.Error(err))
		//任务不存在
		return "", ErrInvalidId
	}
	return user.Phone, nil
}

// GetTasksByStatus 根据任务状态查询任务
func GetTasksByStatus(status string) (tasks []*models.Tasks, err error) {
	err = Conn.Table("tasks").Where("task_status = ?", status).Order("publish_time DESC").Find(&tasks).Error
	if err != nil {
		zap.L().Error("GetAllTasks() Select failed", zap.Error(err))
		return nil, err
	}
	return tasks, nil
}

// UpdateTaskImage 更新用户凭证的图片
func UpdateTaskImage(Id int64, image []byte) error {
	// 执行数据库更新操作
	if err := Conn.Model(&models.Tasks{}).Where("id = ?", Id).Update("completion_image", image).Error; err != nil {
		return err
	}
	return nil
}

// GetPublishPhone 获取任务中接收人的手机号
func GetPublishPhone(id int) (phone string, err error) {
	var task *models.Tasks
	err = Conn.Debug().Where("id=?", id).First(&task).Error
	if err != nil {
		zap.L().Error("GetTask(id int) First(&task) failed", zap.Error(err))
		//任务不存在
		return "", ErrInvalidId
	}
	var user *models.Users
	err = Conn.Debug().Where("uid=?", task.PublisherId).First(&user).Error
	if err != nil {
		zap.L().Error("GetTask(id int) First(&user) failed", zap.Error(err))
		//任务不存在
		return "", ErrInvalidId
	}
	return user.Phone, nil
}

// GetTaskByID 根据任务 ID 获取任务对象
func GetTaskByID(taskID int64) (*models.Tasks, error) {
	var task models.Tasks
	if err := Conn.First(&task, taskID).Error; err != nil {
		return nil, err
	}
	return &task, nil
}

func StartTimer() {

	fmt.Println("StartTimer开始")
	// 获取当前时间
	currentTime := time.Now()
	// 计算今天晚上10点的时间
	targetTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 8, 21, 0, 0, currentTime.Location())
	// 如果当前时间已经过了今天晚上10点，则将目标时间推迟到明天晚上10
	if currentTime.After(targetTime) {
		targetTime = targetTime.Add(24 * time.Hour)
	}

	// 计算需要等待的时间
	duration := targetTime.Sub(currentTime)

	// 创建定时器，设置等待时间
	timer := time.NewTimer(duration)

	// 等待定时器触发
	<-timer.C

	// 定时器触发后执行操作
	fmt.Println("定时器触发")

	// 在这里调用你想要执行的操作方法
	checkAndUpdateTasks()
	fmt.Println("定时器触发")
	// 定时器触发后，重新启动定时器
	StartTimer()
}
